#ifndef _UTILEX_THREAD_HPP_
#define _UTILEX_THREAD_HPP_

#include <crt_util.h>

#ifdef __cplusplus

class CThread
{
public:
	CThread() {
		thread = INVALID_HANDLE_VALUE;
		m_State = S_ERROR;
	}
	virtual ~CThread() {

	}
	int Start_Thread() {

		rc_assert(thread == INVALID_HANDLE_VALUE, S_ERROR)

		this->Thread_Init();
		int rc = _thread_create(&thread, CThread::thread_proc, this);
		rc_assert(rc == S_SUCCESS, S_ERROR)
		this->WaitSem();
		return S_SUCCESS;
	}

	int Stop_Thread() {
		rc_assert(thread != INVALID_HANDLE_VALUE, S_ERROR)

		this->Thread_UnInit();

		if (this->GetState() != S_SUCCESS)
			this->WaitSem();

		_thread_join(&thread);
		return S_SUCCESS;
	}

	int PostSem() {
		rc_assert(thread != INVALID_HANDLE_VALUE, S_ERROR)
		m_Sem.Post();
		return S_SUCCESS;
	}
	int WaitSem() {
		rc_assert(thread != INVALID_HANDLE_VALUE, S_ERROR)
		m_Sem.Wait();
		return S_SUCCESS;
	}
	static void thread_proc(void* pthis) {
		CThread* p = static_cast<CThread*>(pthis);
		if (p) {
			p->PostSem();
			p->Thread_Run();
			p->SetState(S_SUCCESS);
			p->PostSem();
		}
		else {
			p->PostSem();
		}
	}

	UINT SetState(UINT state) {

		m_State = state;
		return m_State;
	}

	UINT GetState() {

		return m_State;
	}
protected:
	std_method(Thread_Init)() PURE;
	std_method(Thread_Run)() PURE;
	std_method(Thread_UnInit)() PURE;
protected:
	_thread_t		thread;
	CSemHandle		m_Sem;
	UINT			m_State;
};


#endif


#endif
